import java.io.*;
import java.nio.charset.StandardCharsets;

public class Test {
    public static void main(String[] args) throws IOException {
        // Reader 是 Java 标准库提供的最基本的字符输入流
        // Reader 是一个抽象类，它是所有字符输入流的超类。最重要的方法是 int read()
        // public abstract int read() throws IOException;
        // read() 返回一个 Unicode 码元（0-65535），到达末尾返回 -1
        readCharByChar();

        // 把字节流包装成字符流，并指定编码
        readerWithEncoding();

        // 带缓冲的读取，支持整行读取 readLine()
        bufferedReadFile();

        // 在内存中模拟一个 Reader
        stringReaderDemo();

        // 一次性把文件整个读成字符串（Java 11+）
        readAsString("./readme.md");
    }

    /* 逐字符读取，和最原始的 InputStream.read() 类似，但单位是 char */
    public static void readCharByChar() throws IOException {
        try (Reader reader = new FileReader("./readme.md")) {   // 默认编码
            int c;
            while ((c = reader.read()) != -1) {
                System.out.print((char) c);   // 打印字符，而非数字
            }
        }
    }

    /* 指定编码，防止乱码；FileReader 不能选编码，必须用 InputStreamReader 包一层 */
    public static void readerWithEncoding() throws IOException {
        try (Reader reader = new InputStreamReader(
                new FileInputStream("./readme.md"), StandardCharsets.UTF_8)) {
            int c;
            while ((c = reader.read()) != -1) {
                System.out.print((char) c);
            }
        }
    }

    /* 带缓冲的读取，支持 readLine()，性能高 */
    public static void bufferedReadFile() throws IOException {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream("./readme.md"), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {   // 整行读取，不包换行符
                System.out.println(line);
            }
        }
    }

    /* 在内存里模拟一个 Reader，类似 ByteArrayInputStream */
    public static void stringReaderDemo() throws IOException {
        String data = "Hello, 中文!";
        try (Reader reader = new StringReader(data)) {
            int c;
            while ((c = reader.read()) != -1) {
                System.out.print((char) c);
            }
        }
    }

    /* Java 11+ 一次性读成字符串；底层仍是 Reader，只是帮你循环完了 */
    public static void readAsString(String filename) throws IOException {
        // Files.newBufferedReader 默认 UTF-8
        try (BufferedReader reader = java.nio.file.Files.newBufferedReader(
                java.nio.file.Paths.get(filename))) {
            String content = reader.lines()   // 返回 Stream<String>
                                   .reduce((a, b) -> a + "\n" + b)
                                   .orElse("");
            System.out.println("文件内容为：\n" + content);
        }
    }
}